﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Data.SQLite;

namespace Music_Organizer
{

    public partial class MainForm : Form
    {
        Xmlconfig xmlSettings = null;
        SQLiteManager dbManager = null;

        const int applicationRev = 1;
        const int settingsRev = 1;
        const int databaseRev = 1;


        public MainForm()
        {
            InitializeComponent();

            InitializeSettings();
            InitializeDataBase();

            CloudScan(true);
        }

        private void InitializeSettings()
        {
            string settingsFileName = "config.xml";

            xmlSettings = new Xmlconfig(settingsFileName, true);

            bool createNew = false;
            if (xmlSettings.Settings["ConfigVersion"].intValue != settingsRev)
            {
                createNew = true;
            }

            if (createNew)
            {
                xmlSettings.Settings["ApplicationVersion"].intValue = applicationRev;
                xmlSettings.Settings["ConfigVersion"].intValue = settingsRev;
                xmlSettings.Settings["DatabaseVersion"].intValue = 0;

                RootFoldersForm userForm = new RootFoldersForm(@"C:\Libraries\Music", @"C:\Libraries\Music");
                userForm.ShowDialog();

                xmlSettings.Settings["Repository/Cloud/Path"].Value = userForm.CloudRoot;
                xmlSettings.Settings["Repository/Local/Music/Path"].Value = userForm.LocalMusic;
                xmlSettings.Save();
            }
        }
        private void InitializeDataBase()
        {
            dbManager = new SQLiteManager();

            if (dbManager.newDatabase)
            {
                CloudScan(true);
            }

            if (xmlSettings.Settings["DatabaseVersion"].intValue != databaseRev)
            {
                dbManager.Clear();
                CloudScan(true);
                xmlSettings.Settings["DatabaseVersion"].intValue = databaseRev;
            }  

            DisplayCloudLibrary();
        }

        private void DisplayCloudLibrary()
        {
            mainDataView.DataSource = dbManager.Select("Cloud");
        }
            
        private void FakeGUI()
        {
            Icon emptyIcon = new Icon(this.GetType(), "Empty.ico");
            DataGridViewImageColumn typeIconColumn = new DataGridViewImageColumn();
            typeIconColumn.Image = emptyIcon.ToBitmap();
            typeIconColumn.Name = "Type";
            typeIconColumn.SortMode = DataGridViewColumnSortMode.NotSortable;
            typeIconColumn.ImageLayout = DataGridViewImageCellLayout.Zoom;
            typeIconColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            mainDataView.Columns.Insert(0, typeIconColumn);

            DataGridViewTextBoxColumn titleTextColumn = new DataGridViewTextBoxColumn();
            titleTextColumn.Name = "Title";
            titleTextColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            mainDataView.Columns.Add(titleTextColumn);

            DataGridViewTextBoxColumn performerTextColumn = new DataGridViewTextBoxColumn();
            performerTextColumn.Name = "Performer";
            performerTextColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            mainDataView.Columns.Add(performerTextColumn);

            DataGridViewTextBoxColumn yearTextColumn = new DataGridViewTextBoxColumn();
            yearTextColumn.Name = "Year";
            yearTextColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            mainDataView.Columns.Add(yearTextColumn);

            //Rihanna - You Da One
            mainDataView.Rows.Add(1);
            mainDataView.Rows[0].Cells[0].Value = new Icon(this.GetType(), "Music.ico");
            mainDataView.Rows[0].Cells[1].Value = "You Da One";
            mainDataView.Rows[0].Cells[2].Value = "Rihanna";
            mainDataView.Rows[0].Cells[3].Value = "2012";

            //Ke$ha - Animal
            mainDataView.Rows.Add(1);
            mainDataView.Rows[1].Cells[0].Value = new Icon(this.GetType(), "Music.ico");
            mainDataView.Rows[1].Cells[1].Value = "Animal";
            mainDataView.Rows[1].Cells[2].Value = "Ke$ha";
            mainDataView.Rows[1].Cells[3].Value = "2010";

            //Grandma's Boy
            mainDataView.Rows.Add(1);
            mainDataView.Rows[2].Cells[0].Value = new Icon(this.GetType(), "Movie.ico");
            mainDataView.Rows[2].Cells[1].Value = "Grandma's Boy";
            mainDataView.Rows[2].Cells[2].Value = "Allen Covert";
            mainDataView.Rows[2].Cells[3].Value = "2006";

            //Shinedown - The Sound of Madness
            mainDataView.Rows.Add(1);
            mainDataView.Rows[3].Cells[0].Value = new Icon(this.GetType(), "Music.ico");
            mainDataView.Rows[3].Cells[1].Value = "The Sound of Madness";
            mainDataView.Rows[3].Cells[2].Value = "Shinedown";
            mainDataView.Rows[3].Cells[3].Value = "2000";

            for (int column = 0; column < mainDataView.Columns.Count; column++)
            {
                mainDataView.Rows[mainDataView.Rows.Count - 1].Cells[column].Value = null;
            }
        }

        ProgressBarWindow pbMusicImport;
        private void MusicImport()
        {
            System.Windows.Forms.FolderBrowserDialog tmpDialog = new System.Windows.Forms.FolderBrowserDialog(); //Standard browse form
            tmpDialog.ShowDialog();

            MusicImport(tmpDialog.SelectedPath);
        }
        private void MusicImport(string folderPath)
        {
            if (!bwMusicScan.IsBusy)
            {
                    pbMusicImport = new ProgressBarWindow();
                    pbMusicImport.FormClosed += new FormClosedEventHandler(pbMusicImport_FormClosed);
                    pbMusicImport.Show();

                bwMusicScan.WorkerSupportsCancellation = true;
                bwMusicScan.WorkerReportsProgress = true;
                bwMusicScan.RunWorkerAsync((object)folderPath);
            }
        }
        private void bwMusicImport_DoWork(object sender, DoWorkEventArgs e)
        {
            Music mClass = new Music();

            bwMusicScan.ReportProgress(0,(object)"Scanning Folder");

            if (bwMusicScan.CancellationPending)
                return;

            DataTable resultSearchFolder = mClass.SearchFolder((string)e.Argument);

            bwMusicScan.ReportProgress(0, (object)"Scanning for Duplicates");

            if (bwMusicScan.CancellationPending)
                return;

            DataTable sortedSearchFolder = dbManager.RemoveDuplicateMusic(resultSearchFolder);

            if (bwMusicScan.CancellationPending)
                return;

            bwMusicScan.ReportProgress(0, (object)"Adding files to database");
            //dbManager.Insert(sortedSearchFolder, "Cloud");
            //dbManager.Commit();

            e.Result = sortedSearchFolder;
        }
        private void bwMusicImport_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (pbMusicImport != null)
            {
                pbMusicImport.Task = (string)e.UserState;

                pbMusicImport.Value = e.ProgressPercentage;

                if (pbMusicImport.Value > 1)
                    pbMusicImport.Style = ProgressBarStyle.Blocks;
                else
                    pbMusicImport.Style = ProgressBarStyle.Marquee;
            }
        }
        private void bwMusicImport_RunWorkerComplete(object sender, RunWorkerCompletedEventArgs e)
        {
            if (pbMusicImport != null)
            {
                try { pbMusicImport.Close(); }
                catch { }

                mainDataView.DataSource = e.Result;
            }

            pbMusicImport = null;
        }
        private void pbMusicImport_FormClosed(object sender, FormClosedEventArgs e)
        {
            if(bwMusicScan.IsBusy)
                bwMusicScan.CancelAsync();
        }

        ProgressBarWindow pbFileScan;
        private void CloudScan(bool showProgress)
        {
            FileScan(showProgress, xmlSettings.Settings["Repository/Cloud/Path"].Value, false);
        }
        private void uploadCloud_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog tmpDialog = new FolderBrowserDialog();
            tmpDialog.Description = "Select folder to upload";
            tmpDialog.ShowNewFolderButton = true;
            tmpDialog.ShowDialog();
            string scanPath = tmpDialog.SelectedPath;

            FileScan(true, scanPath, true);
        }
        private void FileScan(bool showProgress, string path, bool copyToCloud)
        {
            if (!bwFileScan.IsBusy)
            {
                if (showProgress)
                {
                    pbFileScan = new ProgressBarWindow();
                    pbFileScan.FormClosed += new FormClosedEventHandler(pbFileScan_FormClosed);
                    pbFileScan.Show();
                }

                object[] arg = new object[2];
                arg[0] = (object)path;
                arg[1] = (object)copyToCloud;

                bwFileScan.WorkerReportsProgress = true;
                bwFileScan.WorkerSupportsCancellation = true;
                bwFileScan.RunWorkerAsync(arg);
            }
            else
            {
                MessageBox.Show("Please wait for current action to complete");
            }
        }
        private void bwFileScan_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] Arg = (object[])e.Argument;
            string path = (string)Arg[0];
            bool copyToCloud = (bool)Arg[1];

            Music mClass = new Music();

            if (bwFileScan.CancellationPending)
                return;

            bwFileScan.ReportProgress(0, (object)"Scanning Cloud");

            DataTable resultSearchFolder = mClass.SearchFolder(path);

            if (bwFileScan.CancellationPending)
                return;

            bwFileScan.ReportProgress(0, (object)"Finding New Files");

            DataTable sortedSearchFolder = dbManager.RemoveDuplicateMusic(resultSearchFolder);

            if (bwFileScan.CancellationPending)
                return;

            if (copyToCloud)
            {
                for (int i = 0; i < sortedSearchFolder.Rows.Count; i++)
                {
                    //Update Progress
                    bwFileScan.ReportProgress((int)(100.0 * i / sortedSearchFolder.Rows.Count), (object)("Copying " + sortedSearchFolder.Rows[0]["Artist"] + " - " + sortedSearchFolder.Rows[0]["Title"]));

                    //Generate the paste path
                    string pastePath = mClass.GeneratePath(sortedSearchFolder.Rows[i], xmlSettings.Settings["Repository/Cloud/Path"].Value);

                    FileManager tmpFileManager = new FileManager();
                    tmpFileManager.CopyFile((string)sortedSearchFolder.Rows[i]["Path"], pastePath);

                    if (bwFileScan.CancellationPending)
                        return;
                }
            }

            bwFileScan.ReportProgress(100, (object)"Updating Database");

            dbManager.AutoInsert(sortedSearchFolder, "Music");
        }
        private void bwFileScan_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
            if (pbFileScan != null)
            {
                pbFileScan.Task = (string)e.UserState;
                pbFileScan.Value = e.ProgressPercentage;

                if (pbFileScan.Value > 0)
                    pbFileScan.Style = ProgressBarStyle.Continuous;
                else
                    pbFileScan.Style = ProgressBarStyle.Marquee;
            }
        }
        private void bwFileScan_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            if (pbFileScan != null)
            {
                try { pbFileScan.Close(); }
                catch { }
            }

            pbFileScan = null;
        }
        private void pbFileScan_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (bwFileScan.IsBusy)
                bwFileScan.CancelAsync();
        }

        private void searchTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (searchTree.SelectedNode.Name == "Cloud")
            {
                DataTable DT = dbManager.SelectCMD("SELECT Cloud.ID, TypeID.TypeDescription, Cloud.Title FROM TypeID, Cloud WHERE Cloud.TypeID = TypeID.TypeID");
                DT.Columns["TypeDescription"].ColumnName = "Media Type";
                mainDataView.DataSource = DT;
                mainDataView.Columns["ID"].Visible = false;
                mainDataView.ContextMenuStrip = rcMoveFiles;
            }
            else if (searchTree.SelectedNode.Name == "Music" && searchTree.SelectedNode.Parent.Name == "Cloud")
            {
                mainDataView.DataSource = dbManager.SelectCMD("SELECT Cloud.ID, Cloud.Title, Music.Artist, Music.Album, Music.Track, Music.Genre, Music.Year FROM Music,Cloud Where Cloud.ID = Music.ID");
                mainDataView.Columns["ID"].Visible = false;
                mainDataView.ContextMenuStrip = rcMoveFiles;
            }
        }
        private void mainDataView_CellContextMenuStripNeeded(object sender, System.Windows.Forms.DataGridViewCellContextMenuStripNeededEventArgs e)
        {
            if (mainDataView.SelectedRows.Count <= 1)
            {
                for (int i = 0; i < mainDataView.SelectedRows.Count; i++)
                {
                    mainDataView.SelectedRows[i].Selected = false;
                }

                mainDataView.Rows[e.RowIndex].Selected = true;
            }
            else
            {
                //Assume user wants to select more than one row
            }
        }

        ProgressBarWindow pbrcMoveFiles;
        private void rcCopyLocal_Click(object sender, EventArgs e)
        {
            if (!bwrcMoveFiles.IsBusy)
            {
                pbrcMoveFiles = new ProgressBarWindow();
                pbrcMoveFiles.Title = "Copying Files to Local";
                pbrcMoveFiles.FormClosed += new FormClosedEventHandler(pbrcMoveFiles_FormClosed);
                pbrcMoveFiles.Show();

                object[] bwrcArg = new object[mainDataView.SelectedRows.Count + 1];
                bwrcArg[0] = xmlSettings.Settings["Repository/Local/Music/Path"].Value;
                for (int i = 0; i < mainDataView.SelectedRows.Count; i++)
                {
                    int copyIndex = mainDataView.SelectedRows[i].Index;
                    DataTable DT = (DataTable)mainDataView.DataSource;
                    bwrcArg[i + 1] = (int)DT.Rows[copyIndex]["ID"];
                }

                bwrcMoveFiles.WorkerReportsProgress = true;
                bwrcMoveFiles.WorkerSupportsCancellation = true;
                bwrcMoveFiles.RunWorkerAsync(bwrcArg);
            }
            else
            {
                MessageBox.Show("Already " + pbrcMoveFiles.Title);
            }
        }
        private void rcExport_Click(object sender, EventArgs e)
        {
            if (!bwrcMoveFiles.IsBusy)
            {
                FolderBrowserDialog tmpDialog = new FolderBrowserDialog();
                tmpDialog.Description = "Select folder to export files";
                tmpDialog.ShowNewFolderButton = true;
                tmpDialog.ShowDialog();
                string exportFolder = tmpDialog.SelectedPath;

                pbrcMoveFiles = new ProgressBarWindow();
                pbrcMoveFiles.Title = "Exporting Files to Folder";
                pbrcMoveFiles.FormClosed += new FormClosedEventHandler(pbrcMoveFiles_FormClosed);
                pbrcMoveFiles.Show();

                object[] bwrcArg = new object[mainDataView.SelectedRows.Count + 1];
                bwrcArg[0] = exportFolder;
                for (int i = 0; i < mainDataView.SelectedRows.Count; i++)
                {
                    int copyIndex = mainDataView.SelectedRows[i].Index;
                    DataTable DT = (DataTable)mainDataView.DataSource;
                    bwrcArg[i + 1] = (int)DT.Rows[copyIndex]["ID"];
                }

                bwrcMoveFiles.WorkerReportsProgress = true;
                bwrcMoveFiles.WorkerSupportsCancellation = true;
                bwrcMoveFiles.RunWorkerAsync(bwrcArg);
            }
            else
            {
                MessageBox.Show("Already " + pbrcMoveFiles.Title);
            }
        }
        private void bwrcMoveFiles_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] eArg = (object[])e.Argument;

            for (int i = 1; i < eArg.Length; i++)
            {
                int copyID = (int)eArg[i];

                DataTable trackDT = dbManager.SelectCMD("SELECT Music.Artist, Music.Album, Cloud.Title, Cloud.Extention, Cloud.Path FROM Music,Cloud Where Cloud.ID = " + copyID + " AND Music.ID = " + copyID);

                Music tmpMusic = new Music();
                string pastePath = tmpMusic.GeneratePath(trackDT.Rows[0], (string)eArg[0]);

                bwrcMoveFiles.ReportProgress((int)(100.0*i/mainDataView.SelectedRows.Count),(object)(trackDT.Rows[0]["Artist"] + " - " + trackDT.Rows[0]["Title"]));

                FileManager tmpFileManager = new FileManager();
                tmpFileManager.CopyFile((string)trackDT.Rows[0]["Path"], pastePath);

                if (bwrcMoveFiles.CancellationPending)
                    break;
            }
        }
        private void bwrcMoveFiles_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
            if (pbrcMoveFiles != null)
            {
                pbrcMoveFiles.Task = (string)e.UserState;
                pbrcMoveFiles.Value = e.ProgressPercentage;
            }
        }
        private void bwrcMoveFiles_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            if (pbrcMoveFiles != null)
            {
                pbrcMoveFiles.Task = "Complete";
                pbrcMoveFiles.Value = 100;

                pbrcMoveFiles.Close();
                pbrcMoveFiles = null;
            }
        }
        void pbrcMoveFiles_FormClosed(object sender, FormClosedEventArgs e)
        {
            if(bwrcMoveFiles.IsBusy)
                bwrcMoveFiles.CancelAsync();
        }

        private void MainForm_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            dbManager.Close();
            xmlSettings.Commit();
        }
    }
}


